package com.fyl.validation.aop;

import com.fyl.utils.ResponseUtil;
import com.fyl.validation.AbstractValidator;
import com.fyl.validation.anno.ValidationParam;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;

import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;

public class ValidationMethodInterceptor extends AbstractValidator implements MethodInterceptor, BeanFactoryAware {

    private BeanFactory beanFactory;

    @Autowired
    HttpServletResponse response;

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {

        Method method = invocation.getMethod();
        Parameter[] parameters = method.getParameters();
        Object[] arguments = invocation.getArguments();
        List<String> messages = new ArrayList<>();
        for (int i = 0; i < parameters.length; i++) {
            Parameter param = parameters[i];
            Object arg = arguments[i];
            if (param.isAnnotationPresent(ValidationParam.class)) {
                messages.addAll(this.validate(arg));
            }
        }
        if (!messages.isEmpty()) {
            ResponseUtil.cutResponse(HttpStatus.BAD_REQUEST.value(), String.join(",", messages), response);
            return null;
        }
        return invocation.proceed();
    }


    @Override
    public <T> T getBean(Class<T> clazz) {
        return this.beanFactory.getBean(clazz);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
}
